package pt.utl.ist.ginger3d.domain;

import java.util.HashMap;
import java.util.Map;

import pt.utl.ist.ginger3d.domain.types.IBlockType;

public class Block extends Tag implements Cloneable {
	
	private IBlockType type;
	private String typeId;
	
	public Block(String name, String typeId, Map<String, String> properties) {
		super(name, properties);
		this.typeId = typeId;
		this.type = BlockTypeHandler.getInstance().getType(typeId);
		
		
		// add default properties
		if(type.getDefaultProperties() != null) {
			for(Map.Entry<String, String> property : type.getDefaultProperties().entrySet()) {
				if(!properties.containsKey(property.getKey())) {
					properties.put(property.getKey(), property.getValue());
				}
			}
		}
		
		// assert required properties
		if(type.getRequiredProperties(typeId) != null) {
			for(String propertyName : type.getRequiredProperties(typeId)) {
				if(!properties.containsKey(propertyName)) {
					System.err.println("Block name: " + name + " -> missing required property: " + propertyName);
					System.exit(1);
				}
			}
		}
	}

	public IBlockType getType() {
		return type;
	}
	
	@Override
	protected Object clone() {
		try {
			Block block = (Block) super.clone();
			block.setProperties(new HashMap<String, String>(getProperties()));
			return block;
		} 
		catch (CloneNotSupportedException e) { 
			return null;
		}
	}

	@Override
	protected String[] getRequiredProperties() {
		return type.getRequiredProperties(typeId);
	}

	public Block doCopy() {
		return (Block) clone();
	}
	
	@Override
	public String toString() {
		return getClass().getSimpleName() + " (" + getName() + "/" + hashCode() + ") ";
	}
}
